package com.quick.shiro.realm;

import com.alibaba.fastjson.JSON;
import com.quick.common.dto.UserAdminDto;
import com.quick.common.enums.HttpStatus;
import com.quick.common.result.CodeException;
import com.quick.common.utils.Md5;
import com.quick.shiro.feign.AdminFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;

/**
 * 授权相关服务-shiro
 *
 * @author qiguliuxing
 * @since 1.0.0
 */
@Component
@Slf4j
public class AdminAuthorizingRealm extends AuthorizingRealm {

    @Autowired
    private AdminFeignClient mAdminFeignClient;

    //doGetAuthorizationInfo主要是获取用户的角色和权限，并交给Shiro去判断是否具有访问资源的权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }

        UserAdminDto admin = (UserAdminDto) getAvailablePrincipal(principals);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 角色id
        String roleIds = admin.getRoleIds();
        List<String> roleIdList = JSON.parseArray(roleIds, String.class);
//		// 角色名称
        Set<String> roles = mAdminFeignClient.queryRoleByIds(roleIdList);
//		// 角色的权限组
		Set<String> permissions = mAdminFeignClient.queryPermissionByRoleIds(roleIdList);

        info.setRoles(roles);
        info.setStringPermissions(permissions);

        return info;
    }

    //重写doGetAuthenticationInfo（用于登录验证）
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {

        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        String password = new String(upToken.getPassword());

        if (StringUtils.isEmpty(username)) {
            throw new AccountException("用户名不能为空");
        }
        if (StringUtils.isEmpty(password)) {
            throw new AccountException("密码不能为空");
        }

        // 查询用户
        List<UserAdminDto> admin = mAdminFeignClient.findAdminFromUsername(username);
        if (admin.size() == 0) {
            throw new CodeException(HttpStatus.USER_NOT_EXIST_FAIL);
        }

        UserAdminDto userAdminDto = admin.get(0);

        if (userAdminDto == null) {
            throw new CodeException(HttpStatus.USER_NOT_EXIST_FAIL);
        }

        if (!Md5.md5(password).equals(userAdminDto.getPassword())){
            throw new CodeException(HttpStatus.USER_PASSWORD_NOT_MATCH);
        }
        // 如果找到这个用户. 通过
        return new SimpleAuthenticationInfo(userAdminDto, password, getName());
    }

}
